﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using fivescomplement.Models;
using System.Security.Cryptography;
using System.Web.Security;
using System.Net;
using System.Net.Mail;
using System.Data;

namespace fivescomplement.Controllers
{

    [HandleError]
    public class AccountController : Controller
    {

        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                using (var context = new C335263_teacherharvestEntities())
                {
                    var user = from u in context.Pswtks
                               where u.UserID == model.UserName
                               select u;

                    if (user.ToList().Count == 1)
                    {
                        if (user.First().Psw == CreatePasswordHash(model.Password, user.First().Salt))
                        {
                            Session["logged"] = user.First().UserID;
                            FormsService.SignIn(model.UserName, false /* createPersistentCookie */);

                            Session["Type"] = user.First().UserRole;
                            Session["Reference"] = user.First().Salt;

                            if (user.First().UserRole == 1) //user 1 is Student
                            {
                                return RedirectToAction("Index", "Report");
                            }
                            if (user.First().UserRole == 2) //user 2 is Faculty
                            {
                                return RedirectToAction("Index", "Faculty");
                            }
                            else if (user.First().UserRole == 3) //user 3 is Admin
                            {
                                return RedirectToAction("Index", "Admin");
                            }


                        }
                    }
                }
                ModelState.AddModelError("_loginError", "Error in username and password");
                if (!ModelState.IsValid)
                    return View();

                return RedirectToAction("LogOn", "Account");
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
           
            FormsService.SignOut();
            Session.Clear();
            return RedirectToAction("Index", "Home");
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        public ActionResult Register()
        {
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View();
        }

        [HttpPost]
        public ActionResult Register(RegisterModel model, string id)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
               // MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);

                using (var context = new C335263_teacherharvestEntities())
                {
                    var studentuser = from u in context.Students
                               where u.Reference == id
                               select u;

                    if (studentuser.ToList().Count == 1) //checking if students table has salt
                    {
                        var existinguser = from u in context.Pswtks
                               where u.Salt == id
                                   select u;
                        if (existinguser.ToList().Count == 0)
                        {
                            Pswtks newuser = Pswtks.CreatePswtks(model.Email.ToLower(), CreatePasswordHash(model.Password, id), model.UserName.ToLower(), id, 1);
                            context.Pswtks.AddObject(newuser);
                            context.SaveChanges();
                            FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
                            return RedirectToAction("Index", "Report");
                        }
                        else
                        {
                            ModelState.AddModelError("", "Some Error");
                            //this user already created an account via email link. redirect to something with a message.
                        }
                            
                    }
                    else
                    {
                        //checking if Instructors table has salt
                        var teacheruser = from u in context.Instructors
                               where u.Reference == id
                               select u;

                        if (teacheruser.ToList().Count == 1)
                        {
                            var existinguser = from u in context.Pswtks
                                               where u.Salt == id
                                               select u;
                            if (existinguser.ToList().Count == 0)
                            {
                                Pswtks newuser = Pswtks.CreatePswtks(model.Email.ToLower(), CreatePasswordHash(model.Password, id), model.UserName.ToLower(), id, 2);
                                context.Pswtks.AddObject(newuser);
                                context.SaveChanges();
                                FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
                                return RedirectToAction("Index", "Faculty");
                            }
                            else
                            {
                                ModelState.AddModelError("", "Some Error");
                                //this user already created an account via email link. redirect to something with a message.
                            }
                        }
                        else
                        {
                            //error finding reference
                        }

                    }

 
                    return RedirectToAction("Index", "Home");
                }
            }

            // If we got this far, something failed, redisplay form
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View();
        }
        
        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                    
                }
            }

            // If we got this far, something failed, redisplay form
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePasswordSuccess
        // **************************************

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        private static string CreateSalt()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] byteArr = new byte[64];
            rng.GetBytes(byteArr);

            return Convert.ToBase64String(byteArr);
        }

        private static string CreatePasswordHash(string password, string salt)
        {
            string passwrodSalt = String.Concat(password, salt);
            string hashedPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(passwrodSalt, "sha1");
            return hashedPwd;
        }

        #region SendEmail

        public Boolean sendEmail(String Email, String Subject, String Message)
        {
            Boolean isSent = false;

            try
            {
                MailMessage mm = new MailMessage("webmaster@fivescompliment.com", Email);

                mm.Subject = Subject;
                mm.Body = "Name: " + Message + "<br /><br />Testing: ";
                mm.IsBodyHtml = true;
                SmtpClient smtp = new SmtpClient();
                smtp.Host = "mail.fivescompliment.com";
                //set EnambleSsl to True if using Gmail host
                smtp.EnableSsl = false;
                System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
                NetworkCred.UserName = "webmaster@fivescompliment.com";
                NetworkCred.Password = "Passw0rd12!";
                smtp.UseDefaultCredentials = true;
                smtp.Credentials = NetworkCred;
                smtp.Port = 587;
                smtp.Send(mm);

                isSent = true;
            }
            catch
            {
            }

            return isSent;
        }

        #endregion

    }
}
